package com.fjwt.gz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fjwt.gz.components.mq.model.ExportExcelMQ;
import com.fjwt.gz.components.mq.vender.IMQSender;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.entity.SysUser;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.dto.StatScoreNumMonthDTO;
import com.fjwt.gz.db.entity.StatScoreNumMonthEntity;
import com.fjwt.gz.db.vo.StatScoreNumDayVO;
import com.fjwt.gz.db.vo.StatScoreNumMonthVO;
import com.fjwt.gz.service.mapper.StatScoreNumMonthMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 统计：机构积分统计月表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-07-24
 */
@Slf4j
@Service
public class StatScoreNumMonthService extends ServiceImpl<StatScoreNumMonthMapper, StatScoreNumMonthEntity> {

    @Autowired
    private StatScoreRecordService statScoreRecordService;
    @Autowired
    private SysExportTaskService sysExportTaskService;
    @Autowired
    private IMQSender mqSender;

    private static final String STAT_TYPE_MONTH = "month";
    private static final int BATCH_SIZE = 1000;

    public IPage selectScoreNumMonthStatistics(IPage<StatScoreNumMonthEntity> iPage, StatScoreNumMonthDTO scoreNumMonthDTO) {
        if (ObjectUtils.isEmpty(scoreNumMonthDTO.getStatDate())) {
            //获取上个月的日期
            scoreNumMonthDTO.setStatDate(DateUtil.lastMonth());
        }
        return page(iPage, StatScoreNumMonthEntity.gw());
    }

    public void export(StatScoreNumMonthDTO scoreNumMonthDTO, SysUser sysUser) {
        //导出统计月份
        scoreNumMonthDTO.setStatTime(ObjectUtils.isEmpty(scoreNumMonthDTO.getStatDate()) ? DateUtil.format(DateUtil.lastMonth(), "yyyyMM")
                : DateUtil.format(scoreNumMonthDTO.getStatDate(), "yyyyMM"));
        List<StatScoreNumMonthVO> list = baseMapper.selectExportScoreNumMonth(scoreNumMonthDTO);
        if (CollUtil.isEmpty(list)) {
            log.info("没有数据");
            throw new BizException("无数据可导出");
        }
        String fileName = scoreNumMonthDTO.getStatTime() + "福分统计数据报表";
        // 添加导出任务记录
        Long exportTaskId = sysExportTaskService.addExportTask(sysUser, fileName,
                Constants.EXPORT_TASK_ENUM.REQUEST_CODE.SCORE_NUM_MONTH, Constants.EXPORT_TASK_ENUM.RESOURCE_TYPE.FANS,
                JSONObject.toJSONString(scoreNumMonthDTO));
        // 发送mq
        mqSender.send(ExportExcelMQ.build(exportTaskId));

    }

    public List<StatScoreNumMonthVO> selectExportScoreNumMonth(StatScoreNumMonthDTO scoreNumMonthDTO) {
        return baseMapper.selectExportScoreNumMonth(scoreNumMonthDTO);
    }


    public void getScoreNumMonthStatistics(DateTime lastMonth) {

        String time = DateUtil.format(lastMonth, "yyyyMM");
        // 总体福分统计
        List<StatScoreNumDayVO> records = statScoreRecordService.getScoreNumDayOrMonthStatistics(STAT_TYPE_MONTH, time);
        //统计迁移福分
        List<StatScoreNumDayVO> syncScoreDay = statScoreRecordService.getSyncScoreNumDayOrMonthStatistics(STAT_TYPE_MONTH, time);
        //获取上月核销卡券所用的福分
        List<StatScoreNumMonthVO> consumeCouponYuan = statScoreRecordService.getConsumeCouponYuan(time);
        if (records.isEmpty()) {
            return;
        }

        // 数据转换
        List<StatScoreNumMonthEntity> statisticsList = convertToStatistics(records, syncScoreDay, consumeCouponYuan);

        // 批量插入统计表
        saveBatchStatistics(statisticsList);
    }

    private List<StatScoreNumMonthEntity> convertToStatistics(List<StatScoreNumDayVO> records, List<StatScoreNumDayVO> syncScoreDay,
                                                              List<StatScoreNumMonthVO> consumeCouponYuan) {
        List<StatScoreNumMonthEntity> result = new ArrayList<>();

        Map<String, StatScoreNumDayVO> syncMap = new HashMap<>();
        if (CollUtil.isNotEmpty(syncScoreDay)) {
            //通过机构号分
            syncMap = syncScoreDay.stream()
                    .filter(vo -> ObjectUtils.isNotEmpty(vo.getAgentNo()) && !"0".equals(vo.getAgentNo()))
                    .collect(Collectors.toMap(StatScoreNumDayVO::getAgentNo, entity -> entity));
        }

        Map<String, StatScoreNumMonthVO> consumeMap = new HashMap<>();
        if (CollUtil.isNotEmpty(consumeCouponYuan)) {
            //通过机构号分
            consumeMap = consumeCouponYuan.stream()
                    .filter(vo -> ObjectUtils.isNotEmpty(vo.getAgentNo()) && !"0".equals(vo.getAgentNo()))
                    .collect(Collectors.toMap(StatScoreNumMonthVO::getAgentNo, entity -> entity));
        }

        for (StatScoreNumDayVO record : records) {
            StatScoreNumMonthEntity stat = new StatScoreNumMonthEntity();
            // 处理迁移福分
            StatScoreNumDayVO syncData = syncMap.get(record.getAgentNo());
            stat.setMonthSyncScoreNum(syncData != null ? syncData.getMonthSyncScoreNum() : 0L)
                    .setTotalSyncScoreNum(syncData != null ? syncData.getTotalSyncScoreNum() : 0L);

            // 处理核销福分
            StatScoreNumMonthVO consumeData = consumeMap.get(record.getAgentNo());
            stat.setMonthConsumeCouponYuan(consumeData != null ? consumeData.getMonthConsumeCouponYuan() : 0L);

            // 机构
            switch (record.getAgentLevel()) {
                case 1: stat.setAgentNo(record.getAgentNo1()); break;
                case 2: stat.setAgentNo(record.getAgentNo2()); break;
                case 3: stat.setAgentNo(record.getAgentNo3()); break;
                case 4: stat.setAgentNo(record.getAgentNo4()); break;
                default: stat.setAgentNo("0"); break;
            }

            // 直接映射字段
            stat.setLiteAppId(record.getLiteAppId())
                    .setAgentScoreId(record.getAgentScoreId())
                    .setStatDate(DateUtil.lastMonth())
                    .setTotalUnusedScoreNum(record.getTotalScoreNum() - record.getTotalUsedScoreNum())
                    .setTotalUsedScoreNum(record.getTotalUsedScoreNum())
                    .setTotalOverScoreNum(record.getTotalOverScoreNum())
                    .setMonthAddScoreNum(record.getMonthAddScoreNum())
                    .setMonthUsedScoreNum(record.getMonthUsedScoreNum())
                    .setMonthOverScoreNum(record.getMonthOverScoreNum())
                    .setMonthAddBaifuScoreNum(record.getMonthAddBaifuScoreNum())
                    .setMonthExchangeCouponScoreNum(record.getMonthExchangeCouponScoreNum())
                    .setAgentNo1(record.getAgentNo1())
                    .setAgentName1(record.getAgentName1())
                    .setAgentNo2(record.getAgentNo2())
                    .setAgentName2(StrUtil.isNotBlank(record.getAgentName2()) ? record.getAgentName2() : "")
                    .setAgentNo3(record.getAgentNo3())
                    .setAgentName3(StrUtil.isNotBlank(record.getAgentName3()) ? record.getAgentName3() : "")
                    .setAgentNo4(record.getAgentNo4())
                    .setAgentName4(StrUtil.isNotBlank(record.getAgentName4()) ? record.getAgentName4() : "");



            result.add(stat);
        }

        return result;
    }

    private void saveBatchStatistics(List<StatScoreNumMonthEntity> list) {
        if (CollUtil.isEmpty(list)) {
            return;
        }
        int total = list.size();

        for (int i = 0; i < total; i += BATCH_SIZE) {
            int end = Math.min(i + BATCH_SIZE, total);
            List<StatScoreNumMonthEntity> subList = list.subList(i, end);
            baseMapper.insert(subList);
        }
    }
}
